﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Windows.Input;
using System.IO;
using Kokomo.Environment;
using System.Windows;
using System.Threading;
using System.Windows.Media;
using System.Windows.Threading;
using Kokomo.Environment.Services;
using Kokomo.Environment.Documents;
using Kokomo.PeInspector.Settings;

namespace Kokomo.PeInspector.Reflection
{
	public class SourceDocumentViewModel : FlowDocumentViewModelBase
	{
		public FileType FileType { get; private set; }

		public SourceDocumentViewModel(
			Action<ICodeWriter> sourceBuilderDelegate,
			NavigationContext navigationContext,
			FileType fileType,
			string title
			)
			: base(navigationContext, title)
		{
			if (sourceBuilderDelegate == null) throw new ArgumentNullException("sourceBuilderDelegate");
			if (fileType == null) throw new ArgumentNullException("fileType");

			SourceViewSettings viewSettings = AssemblyAnalyzerEditor.SourceViewSettings;

			if (viewSettings.FontFamilyName != null)
				this.FontFamily = new FontFamily(viewSettings.FontFamilyName);
			if (viewSettings.FontSize != 0)
				this.FontSize = viewSettings.FontSize;
			this._sourceBuilderDelegate = sourceBuilderDelegate;
			this.FileType = fileType;
		}

		protected override FlowDocument CreateSourceDocument()
		{
			FlowDocument document = base.CreateSourceDocument();
			document.FontFamily = this.FontFamily;
			document.FontSize = this.FontSize;
			document.PageWidth = 5000;

			return document;
		}

		private Action<ICodeWriter> _sourceBuilderDelegate;

		protected override void BuildDocumentAsync(FlowDocument document)
		{
			FlowDocumentBuilder builder = new FlowDocumentBuilder(document);
			FlowDocumentCodeWriter flowDocumentWriter = new FlowDocumentCodeWriter(builder, this.NavigationContext.NavigateToCommand);
			this._sourceBuilderDelegate(flowDocumentWriter);
		}

		protected override void SaveDocument()
		{
			FileDialogOptions options = new FileDialogOptions()
			{
				FileTypes = new FileType[] { this.FileType, AssemblyAnalyzerEditor.FlowDocumentFileType },
				Title = UiString.FromString(Messages.SaveSourceFileTitle),
				InitialFileName = this.Title
			};
			string sourceFileName = EnvironmentServices.UiService.ShowSaveFileDialog(options);

			if (sourceFileName != null)
			{
				using (StreamWriter writer = new StreamWriter(sourceFileName))
				{
					if (options.SelectedFileType == AssemblyAnalyzerEditor.FlowDocumentFileType)
					{
						System.Windows.Markup.XamlWriter.Save(this.Document, writer);
					}
					else
					{
						TextCodeWriter codeWriter = new TextCodeWriter(writer);
						this._sourceBuilderDelegate(codeWriter);
					}
				}
			}
		}

		#region Options
		private bool _isOptionsPaneVisible;
		public bool IsOptionsPaneVisible
		{
			get { return this._isOptionsPaneVisible; }
			set
			{
				this._isOptionsPaneVisible = value;
				this.OnPropertyChanged("IsOptionsPaneVisible");
			}
		}
		#endregion
		#region Font
		protected override void OnFontFamilyChanged()
		{
			base.OnFontFamilyChanged();
			FontFamily family = this.FontFamily;
			if (family != null)
				AssemblyAnalyzerEditor.SourceViewSettings.FontFamilyName = this.FontFamily.Source;
		}
		protected override void OnFontSizeChanged()
		{
			base.OnFontSizeChanged();
			AssemblyAnalyzerEditor.SourceViewSettings.FontSize = this.FontSize;
		}

		public CodeTextFormatItem[] CodeTextFormatItems
		{
			get { return AssemblyAnalyzerEditor.CodeTextFormatItems; }
		}
		#endregion
	}
}
